package com.logic.battle
{
	import com.action.ActionAttack;
	import com.action.ActionBullet;
	import com.action.ActionDefence;
	import com.action.ActionDie;
	import com.action.ActionHurt;
	import com.action.ActionJump;
	import com.action.ActionMove;
	import com.action.ActionStand;
	import com.action.ActionTurn;
	import com.action.BaseAction;
	import com.action.attack.ActionAttackNormal;
	import com.action.bullet.ActionBulletNormal;
	import com.action.hurt.ActionHurtNormal;
	import com.action.hurt.ActionHurtState;
	import com.keyboard.KeyboardManager;
	import com.logic.player.Property;
	import com.net.udp.UDPServer;
	import com.resource.animation.Animation;
	import com.resource.animation.AnimationCacher;
	import com.resource.unit.ActionUnit;
	import com.stage.battle.BattleField;
	import com.stage.battle.BattleTextManager;
	import com.stage.battle.FlowText;
	import com.stage.item.BasePlayer;
	import com.stage.item.Player;
	
	import flash.display.Sprite;
	import flash.geom.Point;
	import flash.ui.Keyboard;
	
	import mx.core.Application;

	public class BattleLogic
	{
		public static var hostId:String; // 战斗时的主机id
		public static var team1:Array; // 主队，相对的，如果是是当前客户端所在的队伍则为主队
		public static var team2:Array; // 客队
		public static var bullet1:Array; // 主队释放的子弹
		public static var bullet2:Array; // 客队释放的子弹
		public static var playerList:Object = {};
		public static var thisPlayer:Player;
		
		public static var bulletIdNum:int = 0;
		public static var bulletList:Object = {};
		
		public static var keyPressed:Object = {};
		
		public static var aid:String; // 当前客户端角色aid，临时
		

		/**
		 * 初始化战斗场景，服务端推送战斗信息
		 */
		public static function onBattleInfo(host:String, info:Object):void{
			aid = Application.application.userName.text;
			hostId = host;
			
			var container:Sprite = Application.application.container;
			container.graphics.lineStyle(1, 0xff00ff);
			container.graphics.moveTo(200, 0);
			container.graphics.lineTo(200, 500);
			container.graphics.moveTo(0, 400);
			container.graphics.lineTo(600, 400);
			
			var t1:Array = info.team1;
			for(var i:int=0; i<t1.length; i++){
				var player:Player = new Player(t1[i], BattleField.getInstance().middleLayer);
				player.x = 1000;
				player.y = 800;
				player.shieldY = 800;
				playerList[player.data.aid] = player;
				player.play();
				player.visible = true; // 不可缺少的显示角色的两步
				player.act = ActionUnit.STAND;
				player.action = new ActionStand(player);
				player.action.start(player.dir);
				player.property = new Property;
				if(t1[i].aid == aid){
					team1 = info.team1;
					team2 = info.team2;
					thisPlayer = player;
				}
			}
			
			var t2:Array = info.team2;
			for(var i:int=0; i<t2.length; i++){
				var player:Player = new Player(t2[i], BattleField.getInstance().middleLayer);
				player.x = 1400;
				player.y = 800;
				player.shieldY = 800;
				playerList[player.data.aid] = player;
				player.play();
				player.visible = true; // 不可缺少的显示角色的两步
				player.act = ActionUnit.STAND;
				player.action = new ActionStand(player);
				player.action.start(player.dir);
				player.property = new Property;
				if(t2[i].aid == aid){
					team1 = info.team2;
					team2 = info.team1;
					thisPlayer = player;
				}
			}
			
			if(thisPlayer){
				var keyboard:KeyboardManager = 	KeyboardManager.getInstance();
				keyboard.setFuncCode(Keyboard.LEFT, moveLeftDown);
				keyboard.setFuncCode(Keyboard.RIGHT, moveRightDown);
				keyboard.setFuncCodeUp(Keyboard.LEFT, moveLeftUp);
				keyboard.setFuncCodeUp(Keyboard.RIGHT, moveRightUp);
				keyboard.setFunc("a", attackDown);
				keyboard.setFunc("s", skillDown);
				keyboard.setFunc("c", jumpDown);
				keyboard.setFunc("d", defenceDown);
				keyboard.setFuncUp("d", defenceUp);
				
				// 注意：
				// 主机战斗中用到的资源需要预加载
				var animaCacher:AnimationCacher = AnimationCacher.getInstance();
				animaCacher.load("res/bullet.dat");	
			}
			
			BattleField.getInstance().init();
			BattleField.getInstance().lockToPlayer(thisPlayer);
		}
		
		/**
		 * 战斗结束，服务端返回战斗结果
		 */
		public static function onBattleEnd(res:Object):void{
			thisPlayer = null;
			var keyboard:KeyboardManager = 	KeyboardManager.getInstance();
			keyboard.setFuncCode(Keyboard.LEFT, null);
			keyboard.setFuncCode(Keyboard.RIGHT, null);
			keyboard.setFuncCodeUp(Keyboard.LEFT, null);
			keyboard.setFuncCodeUp(Keyboard.RIGHT, null);
			keyboard.setFunc("a", null);
			keyboard.setFunc("s", null);
			keyboard.setFunc("c", null);
			keyboard.setFunc("d", null);
			keyboard.setFuncUp("d", null);
		}
				
		/**
		 * 主机掉线等情况下更换主机
		 */
		public static function onChangeHost(newId:String):void{
			hostId = newId;
		}
		
		/**
		 * 客户端接收动作指令
		 */
		public static function onCommand(aid:String, args:Object):void{
			switch(args.toType){
				case BaseAction.STAND:
					onStand(aid, args.dir);
					break;
				case BaseAction.MOVE:
					onBattleMove(aid, args.dir);
					break;
				case BaseAction.ATTACK:
					onAttack(aid, args.skillId, args.dir);
					break;
				case BaseAction.JUMP:
					onJump(aid, args.num, args.speed, args.dir);
					break;
				case BaseAction.DEFENCE:
					onDefence(aid, args.dir);
					break;
				case BaseAction.DIE:
					onDie(aid, args.dir);
					break;
				case BaseAction.HURT:
					onHurt(aid, args.selfId, args.targetId, args.skillId, args.dir, args.hurtHp, args.bulletId);
					break;
			}
		}
		
		/**
		 * 子弹，包括一切有攻击效果的动画，如子弹，炸弹，地上出现的持续性特效等
		 * 是检测碰撞对象
		 * 注意：这里没有把位置信息传过来
		 */
		public static function onBullet(aid:String, args:Object):void{
			var skillId:String = args.skillId;
			var bulletId:String = args.bulletId;
			var dir:int = args.dir;
			var x:Number = args.x;
			var y:Number = args.y;
			
			var player:Player = playerList[aid];
			if(player){
				var action:ActionBullet = new ActionBulletNormal(player, {skillId:skillId, bulletId:bulletId, dir:dir, x:x, y:y});
				bulletList[action.bulletId] = action;
				action.start();
			}
		}
		
		/**
		 * 战场中的移动
		 */
		public static function onBattleMove(aid:String, dir:int, speed:Number = -1):void{
			if(speed < 0){
				speed = BasePlayer.WALK_SPEED;
			}
			
			var player:Player = playerList[aid];
			if(player){
				if(dir == BasePlayer.WALK_DIR_NONE){
					if(player.action is ActionMove){
						player.action = new ActionStand(player);
						player.action.start(dir);
					}
//					player.walkStop();
				}else{
//					if(player.dir != dir){
//						var actionTurn:ActionTurn = new ActionTurn(player);
//						actionTurn.callback = StateMachine.autoState;
//						player.action = actionTurn;
//						actionTurn.start(dir);
//					}else{
						if(player.action is ActionMove){
							(player.action as ActionMove).dir = dir;
							(player.action as ActionMove).speed = speed;
						}else{
							var action:ActionMove = new ActionMove(player, speed);
							player.action = action;
							action.start(dir);
						}
//						player.walkDir(dir, speed);
//					}
				}
			}
		}
		
		/**
		 * 攻击，包括攻击前摇，收手动作，施法中途可能被打断，可能释放出会移动或不移动或形变的子弹
		 * 是被检测碰撞对象
		 */
		public static function onAttack(aid:String, skillId:String, dir:int):void{
			var player:Player = playerList[aid];
			if(player){
				var action:ActionAttack = new ActionAttackNormal(player, {skillId:skillId});
				action.callback = StateMachine.autoState;
				player.action = action;
				action.start(dir);
				
//				BattleField.getInstance().lockPoint = new Point(0.3, 0.8);
//				BattleField.getInstance().toScale = 1.5;
			}
		}
		

		
		/**
		 * 击中，包括被攻击动画和子弹动画击中，
		 * 是被检测碰撞对象
		 */
		private static var combatNum:int=0;
		public static function onHurt(aid:String, selfId:String, targetId:String, skillId:String, dir:int, hp:int, bulletId:int):void{
			combatNum++;
			
			var selfObj:Player = playerList[selfId];
			var targetObj:Player = playerList[targetId];
			if(targetObj){
				if(targetObj.action is ActionHurt){
					targetObj.action.start(dir);	
				
					BattleTextManager.getInstance().showHitsNum(FlowText.RED, combatNum);
				}else{
					var action:ActionHurt = new ActionHurtNormal(targetObj, {skillId:skillId});
					action.callback = StateMachine.autoState;
					targetObj.action = action;
					action.start(dir);
					
					BattleTextManager.getInstance().showFlowNum(FlowText.RED, -Math.random()*1000, targetObj.x, targetObj.y - 200);
					BattleTextManager.getInstance().showHitsNum(FlowText.RED, combatNum);
				}
			}
			var bullet:ActionBullet = bulletList[bulletId];
			if(bullet){
				delete bulletList[bulletId];
				bullet.end();
			}
		}
		
		/**
		 * 跳跃
		 */
		public static function onJump(aid:String, num:int, speed:int, dir:int):void{
			var player:Player = playerList[aid];
			if(player){
				if(player.action is ActionJump){
					player.action.start(dir);
				}else{
					var action:ActionJump = new ActionJump(player, speed, num);
					action.callback = StateMachine.autoState;
					action.speed = player.action.speed;
					player.action = action;
					action.start(dir);
				}
			}
		}
		
		/**
		 * 防御
		 */
		public static function onDefence(aid:String, dir:int):void{
			var player:Player = playerList[aid];
			if(player){
				if(player.action.type != BaseAction.DEFENCE){
					var action:ActionDefence = new ActionDefence(player);
					action.speed = player.action.speed;
					player.action = action;
					action.start(dir);
				}
			}
		}
		
		/**
		 * 死亡
		 */
		public static function onDie(aid:String, dir:int):void{
			var player:Player = playerList[aid];
			if(player){
				if(player.action.type != BaseAction.DIE){
					var action:ActionDie = new ActionDie(player);
					player.action = action;
					action.start(dir);
				}
			}
		}
		
		/**
		 * 站立
		 */
		public static function onStand(aid:String, dir:int):void{
			var player:Player = playerList[aid];
			if(player){
				if(player.action.type != BaseAction.STAND){
					var action:ActionStand = new ActionStand(player);
					player.action = action;
					action.start(dir);
				}
			}
		}
		
		/************************************************************
		 * 
		 * 工具函数
		 * 
		 ************************************************************/
		public static function inTeam(aid:String, team:Array):Boolean{
			for(var i:int=0; i<team.length; i++){
				if(team[i] && team[i].aid==aid){
					return true;	
				}
			}
			return false;
		}

		/***********************************************************************************
		 * 热键操作
		 ************************************************************************************/
		public static function moveLeftDown():void{
			if(keyPressed[Keyboard.LEFT]){
				
			}else{
				keyPressed[Keyboard.LEFT] = true;
				var args:Object = {};
				args.dir = BasePlayer.WALK_DIR_LEFT;
				args.toType = BaseAction.MOVE;
				UDPServer.getInstance().battleGroup.broadcast("onCommandServer", thisPlayer.data.aid, args);
			}
		}
		
		public static function moveRightDown():void{
			if(keyPressed[Keyboard.RIGHT]){
				
			}else{
				keyPressed[Keyboard.RIGHT] = true;
				var args:Object = {};
				args.dir = BasePlayer.WALK_DIR_RIGHT;
				args.toType = BaseAction.MOVE;
				UDPServer.getInstance().battleGroup.broadcast("onCommandServer", thisPlayer.data.aid, args);
			}
		}
		
		public static function moveLeftUp():void{
			delete keyPressed[Keyboard.LEFT];
			var args:Object = {};
			args.dir = BasePlayer.WALK_DIR_NONE;
			args.toType = BaseAction.MOVE;
			UDPServer.getInstance().battleGroup.broadcast("onCommandServer", thisPlayer.data.aid, args);
		}
		
		public static function moveRightUp():void{
			delete keyPressed[Keyboard.RIGHT];
			var args:Object = {};
			args.dir = BasePlayer.WALK_DIR_NONE;
			args.toType = BaseAction.MOVE;
			UDPServer.getInstance().battleGroup.broadcast("onCommandServer", thisPlayer.data.aid, args);
		}
		
		public static function attackDown():void{
			var args:Object = {};
			args.dir = thisPlayer.dir;
			args.toType = BaseAction.ATTACK;
			args.skillId = "attack";
			UDPServer.getInstance().battleGroup.broadcast("onCommandServer", thisPlayer.data.aid, args);
		}
		
		public static function skillDown():void{
			var args:Object = {};
			args.dir = thisPlayer.dir;
			args.toType = BaseAction.ATTACK;
			args.skillId = "skill";
			UDPServer.getInstance().battleGroup.broadcast("onCommandServer", thisPlayer.data.aid, args); 
		}
		
		public static function jumpDown():void{
			var args:Object = {};
			args.dir = thisPlayer.dir;
			args.toType = BaseAction.JUMP;
			args.num = 3;
			args.speed = 1;
			UDPServer.getInstance().battleGroup.broadcast("onCommandServer", thisPlayer.data.aid, args);
		}
		
		public static function defenceDown():void{
			var args:Object = {};
			args.dir = thisPlayer.dir;
			args.toType = BaseAction.DEFENCE;
			UDPServer.getInstance().battleGroup.broadcast("onCommandServer", thisPlayer.data.aid, args);
		}
		
		public static function defenceUp():void{
			var args:Object = {};
			args.dir = thisPlayer.dir;
			args.toType = BaseAction.STAND;
			UDPServer.getInstance().battleGroup.broadcast("onCommandServer", thisPlayer.data.aid, args);
		}
	}
}